//# GAResourceSyncHandler.js
//# Created by Washaq.Majeed on 5/18/11.
//# Revised by Pawail Qaisar on 9/14/11
//# Minor modification by Abid Hussain on 10/20/2011

exports.GAResourceSyncHandler = Core.Class.subclass ({

	classname: 'GAResourceSyncHandler',

	initialize: function(storeIdsArray, callBackSuccess, callBackFailed, shouldDoSequentialCallsOnly, shouldFallbacktoSequential) {
		this._storeIdsArray = storeIdsArray;
		this._callBackSuccess = callBackSuccess;
		this._callBackFailed = callBackFailed;
		this._shouldDoSequentialCallsOnly = (typeof shouldDoSequentialCallsOnly != "undefined" && shouldDoSequentialCallsOnly != null) ? shouldDoSequentialCallsOnly: false;
		this._shouldFallbacktoSequential = (typeof shouldFallbacktoSequential != "undefined" && shouldFallbacktoSequential != null) ? shouldFallbacktoSequential: true;
		this._timeout = null;
		this._timeoutSet = false;
		this._timeoutCalled = false;	
		if ((this._storeIdsArray != null) && (this._storeIdsArray instanceof Array)){
			this._totalCount = this._storeIdsArray.length;
		}
		else{
			this._totalCount = 0;
		}
		this._detailDownloaderArray = null;
		this._thumbDownloaderArray = null;
		this._totalCount = this._totalCount * 2;
		this._retryCount = -1;
	},

	startLoading: function() {
		if ((this._storeIdsArray != null) && (this._storeIdsArray instanceof Array) && (this._storeIdsArray.length > 0)){
			if (this._shouldDoSequentialCallsOnly == true){
				this.startLoadingSequentially();
			}
			else{
				this.resetBatchCounts();
				
				this._retryCount++;
				
				if (this._retryCount < kGAResourceSyncMaxRetryCount - 1){
					this.startLoadingInBatch();
				}
				else if (this._retryCount == kGAResourceSyncMaxRetryCount - 1 && this._shouldFallbacktoSequential){
					this.startLoadingSequentially();	
				}
				else{
					this.downloadingFailed();
				}
			}
		}
		else{
			this.downloadingComplete();
		}
	},

	/* Batch Download Logic */

	resetBatchCounts: function(){
		this._successCount = 0;
		this._failCount = 0;
	},

	startLoadingInBatch: function(){
		try
		{
			var storeItem = null;
			this.destroyResourceDownloaders();
			this._detailDownloaderArray = new Array();
			this._thumbDownloaderArray = new Array();
			for (var i = 0, l = this._storeIdsArray.length; i < l; i++){
				storeItem = GAGameLoader.getStoreHandler().getStoreObjectForKey(this._storeIdsArray[i]);
				var thisDetailDownloader = new GAResourceDownloader(storeItem , this.resourceDownloadingSuccessful.bind(this), this.resourceDownloadingFailed.bind(this), GAResourceType.kDetail, false);
				thisDetailDownloader.startDownloading();
				this._detailDownloaderArray.push(thisDetailDownloader);
				
				var thisThumbDownloader = new GAResourceDownloader(storeItem , this.resourceDownloadingSuccessful.bind(this), this.resourceDownloadingFailed.bind(this), GAResourceType.kThumb, false);
				thisThumbDownloader.startDownloading();
				this._thumbDownloaderArray.push(thisThumbDownloader);
			}
		}
		catch(_exception)
		{
			console.log('ResourceSync: Batch: Exception: ' + _exception.message);
			this.startLoadingSequentially();
		}
	},

	resourceDownloadingSuccessful: function(savePath){
		this._successCount++;
		this.checkDownloadStatus();
	},

	resourceDownloadingFailed:function (errorCode, errorMsg) {
		this._failCount++;
		console.log("**Failure and FailCount  "+this._failCount +" Total = "+this._totalCount);
		console.log('ResourceSync: Batch: Fail called ' + errorCode + ' ' + errorMsg);
		this.checkDownloadStatus();
	},

	checkDownloadStatus: function(){
		if (this._successCount + this._failCount == this._totalCount){
			if (this._failCount > 0){
				this.startLoading();
			}
			else{
				this.downloadingComplete();	
			}
		}
	},

	/* Sequential Download Logic */

	_timeoutCallback: function(){
		this._timeoutCalled = true;
	},

	_clearTimeout: function(){
		if ((this._timeout != null) && (this._timeout != undefined)){
			if ((this._timeoutSet == true) && (this._timeoutCalled == false)){
				clearTimeout(this._timeout);
			}
		}
		this._timeout = null;
		this._timeoutSet = false;
		this._timeoutCalled = false;
	},

	startLoadingSequentially: function(){
		this.resetBatchCounts();
		this._sequentialCounter = 0;
		if (this._timeoutSet == false){
			this._timeout = setTimeout(this._timeoutCallback.bind(this), kGAResourceSyncTimeout * 1000);
			this._timeoutSet = true;
			this._timeoutCalled = false;
		}
		this.sequentialDownloadDetailForCurrentStoreItem();
	},

	sequentialDownloadDetailForCurrentStoreItem: function(){
		try
		{
			this._sequentialDownloadCurrentStoreItem = GAGameLoader.getStoreHandler().getStoreObjectForKey(this._storeIdsArray[this._sequentialCounter]);
			this.destroySequentialDownloader();
			this._sequentialDownloader = new GAResourceDownloader(this._sequentialDownloadCurrentStoreItem, this.sequentialDownloadSuccessfullForDetail.bind(this), this.sequentialDownloadFailedForDetail.bind(this), GAResourceType.kDetail, false);
			this._sequentialDownloader.startDownloading();
		}
		catch(_exception)
		{
			this.downloadingFailed();
		}
	},

	sequentialDownloadSuccessfullForDetail: function(){
		if (this._timeoutCalled == true){
			this.downloadingFailed();
		}
		else{
			this.sequentialDownloadThumbForCurrentStoreItem();
		}
	},

	sequentialDownloadFailedForDetail: function(){
		if (this._timeoutCalled == true){
			this.downloadingFailed();
		}
		else{
			this.sequentialDownloadDetailForCurrentStoreItem();
		}
	},

	sequentialDownloadThumbForCurrentStoreItem: function(){
		try
		{
			this.destroySequentialDownloader();
			this._sequentialDownloader = new GAResourceDownloader(this._sequentialDownloadCurrentStoreItem, this.sequentialDownloadSuccessfullForThumb.bind(this), this.sequentialDownloadFailedForThumb.bind(this), GAResourceType.kThumb, false);
			this._sequentialDownloader.startDownloading();
		}
		catch(_exception)
		{
			this.downloadingFailed();
		}
		
	},

	sequentialDownloadSuccessfullForThumb: function(){
		this._sequentialCounter++;
		if (this._sequentialCounter < (this._totalCount / 2)){
			if (this._timeoutCalled == true){
				this.downloadingFailed();
			}
			else{
				this.sequentialDownloadDetailForCurrentStoreItem();
			}
		}
		else{
			this.downloadingComplete();
		}
	},

	sequentialDownloadFailedForThumb: function(){
		if (this._timeoutCalled == true){
			this.downloadingFailed();
		}
		else{
			this.sequentialDownloadThumbForCurrentStoreItem();
		}
	},

	/* Download Complete and Fail Callbacks */

	downloadingComplete: function(){
		console.log('ResourceSync: Download Complete');
		GAGameLoader.persistDownloadedResources();
		this.destroyResourceDownloaders();
		this.destroySequentialDownloader();
		this._clearTimeout();
		this._callBackSuccess();
	},

	downloadingFailed: function(){
		console.log('ResourceSync: Download Failed');
		GAGameLoader.persistDownloadedResources();
		this.destroyResourceDownloaders();
		this.destroySequentialDownloader();
		this._clearTimeout();
		this._callBackFailed();
	},

	retrySyncHandler: function(){
		this._retryCount = -1;
		this.startLoading();
	},

	destroyResourceDownloaders: function(){
		if ((this._detailDownloaderArray != null) && (this._detailDownloaderArray instanceof Array)){
			for (var i = 0, l = this._detailDownloaderArray.length; i < l; i++){
				if (this._detailDownloaderArray[i] != null){
					this._detailDownloaderArray[i].destroy();
					this._detailDownloaderArray[i] = null;
				}
			}
		}
		if ((this._thumbDownloaderArray != null) && (this._thumbDownloaderArray instanceof Array)){
			for (var i = 0, l = this._thumbDownloaderArray.length; i < l; i++){
				if (this._thumbDownloaderArray[i] != null){
					this._thumbDownloaderArray[i].destroy();
					this._thumbDownloaderArray[i] = null;
				}
			}
		}
	},

	destroySequentialDownloader: function(){
		if ((this._sequentialDownloader != null) && (this._sequentialDownloader != undefined)){
			this._sequentialDownloader.destroy();
			this._sequentialDownloader = null;
		}
	},

	destroy: function(){
		delete this._detailDownloaderArray;
		delete this._thumbDownloaderArray;
		delete this._storeIdsArray;
		this._callBackSuccess = null;
		this._callBackFailed = null;
	}
});
